Skip to main content

09 程序装载

程序装载的内存问题

装载到内存里面,装载器需要满足两个要求:

  1. 可执行程序加载后占用的内存空间应该是连续的
  2. 需要同时加载很多个程序,并且不能让程序自己规定在内存中加载的位置

在内存里面,找一段连续的内存空间分配给装载的程序,然后把这段连续的内存空间地址,和整个程序指令里指定的内存地址做映射。

指令里用到的内存地址叫作虚拟内存地址(Virtual Memory Address)

实际在内存硬件里面的空间地址叫物理内存地址(Physical Memory Address)

维护一个虚拟内存到物理内存的映射表,实际程序指令执行的时候,通过虚拟内存地址,找到对应的物理内存地址并执行。因为是连续的内存地址空间,所以只需要维护映射关系的起始地址和对应的空间大小。

内存分段

分段(Segmentation):找出一段连续的物理内存和虚拟内存地址进行映射的方法

段:系统分配出来的那个连续的内存空间

内存碎片(Memory Fragmentation)

内存交换(Memory Swapping):把程序占用的内存写到硬盘上,然后再从硬盘上读回来到内存里面。不过读回来的时候,不再把它加载到原来的位置,而是紧跟在已经被占用的内存后面。(Linux swap 硬盘分区)

内存交换时,交换的程序占内存空间大,整个机器会卡顿。

内存分页

内存分页(Paging):少出现一些内存碎片,进行内存交换时,让需要交换写入或者从磁盘装载的数据更少

把整个物理内存空间切成一段段固定尺寸的大小

页(Page):一个连续并且尺寸固定的内存空间(Linux 下通常设置成 4KB)

加载程序的时候,不需要一次性都把程序加载到物理内存中。在进行虚拟内存和物理内存的页之间的映射之后,不真的把页加载到物理内存里,只在程序运行中,需要用到对应虚拟内存页里面的指令和数据时,再加载到物理内存里面去。

当要读取特定的页,却发现数据并没有加载到物理内存里的时候,触发一个来自 CPU 的缺页错误(Page Fault)。操作系统捕捉到这个错误,然后将对应的页,从存放在硬盘上的虚拟内存里读取出来,加载到物理内存里。

可以运行大于实际物理内存的程序

加入一个间接层

通过引入虚拟内存、页映射和内存交换,程序本身不考虑对应的真实的内存地址、程序加载、内存管理等问题。程序把内存当成是一块完整而连续的空间直接使用。